import 'dart:convert';
import 'dart:io';

import 'package:base_lib/index.dart';
import 'package:base_lib/repository/http.dart';
import 'package:doctor_login_lib/cache/userinfo_cache.dart';
import 'package:doctor_login_lib/component.dart';
import 'package:doctor_login_lib/repository/http.dart';
import 'package:base_lib/repository/entity/upload_file_entity.dart'
as UploadBean;
import 'package:doctor_login_lib/login/entity/doctor_login_entity.dart'
as DoctorLoginBean;
import 'entity/save_certify_photo_entity.dart' as SaveCertifyPhotoBean;
import 'package:doctor_login_lib/certification/entity/doctor_certify_entity.dart'
as DoctorCertifyInfoBean;
import 'package:flutter/src/widgets/framework.dart';
import 'package:rxdart/rxdart.dart';

class CertificationBloc extends BaseBloc {
  ///身份证-前
  static const String TYPE_ID_FRONT = "ID-FRONT";

  ///身份证-后
  static const String TYPE_ID_BACK = "ID-BACK";

  ///执业证
  static const String TYPE_PROFESSION = "PROFESSION";

  ///资格证-
  static const String TYPE_QUALIFICATION = "QUALIFICATION";

  ///职称证
  static const String TYPE_TITLE_CERTIFICATE = "TITLE";

  var _idCard = '';
  PublishSubject<String> idCard = PublishSubject();

  var _idCardImg = List<SaveCertifyPhotoBean.Data>();
  PublishSubject<SaveCertifyPhotoBean.Data> idCardFront = PublishSubject();
  PublishSubject<SaveCertifyPhotoBean.Data> idCardBg = PublishSubject();

  var _professionNumber = '';
  PublishSubject<String> professionNumber = PublishSubject();

  var _professionImg = List<SaveCertifyPhotoBean.Data>();
  PublishSubject<List<SaveCertifyPhotoBean.Data>> professionPhoto =
  PublishSubject();

  var _qualificationImg = List<SaveCertifyPhotoBean.Data>();
  PublishSubject<List<SaveCertifyPhotoBean.Data>> qualificationPhoto =
  PublishSubject();

  var _titleCertificateImg = List<SaveCertifyPhotoBean.Data>();
  PublishSubject<List<SaveCertifyPhotoBean.Data>> titleCertificate =
  PublishSubject();


  PublishSubject<bool> loadingStatus = PublishSubject();

  DoctorLoginBean.DoctorUser _doctorUser;

  @override
  void initState() async {
    super.initState();
    var doctorInfo = await UserInfoCache.getInstance().get();
    _doctorUser = doctorInfo;
    getDoctorCertificationInfo();
    loadingStatus.add(false);
  }

  @override
  void dispose() {
    idCard?.close();
    idCardFront?.close();
    idCardBg?.close();
    professionNumber?.close();
    professionPhoto?.close();
    qualificationPhoto?.close();
    titleCertificate?.close();
    loadingStatus?.close();
  }

  void getDoctorCertificationInfo() async {
    var result = await LoginHttp.getCertificationInfo(_doctorUser.keyID);
    if (result.isSuccess) {
      var list = result.data;
      list.forEach((element) {
        var transferBean = SaveCertifyPhotoBean.Data(
            keyID: element.keyID,
            photoFileID: element.photoFileID,
            photoUrl: element.photoUrl,
            modifyUser: element.modifyUser,
            addUser: element.addUser,
            doctorID: element.doctorID,
            certifyCode: element.certifyCode,
            certifyName: element.certifyName);
        switch (element.certifyCode) {
          case "ID-FRONT":
            _idCardImg.insert(0, transferBean);
            idCardFront.add(transferBean);
            break;
          case "ID-BACK":
            _idCard = element.certifyNo;
            idCard.add(_idCard);
            _idCardImg.insert(1, transferBean);
            idCardBg.add(transferBean);
            break;
          case "PROFESSION":
            if (_professionNumber.isEmpty) {
              _professionNumber = element.certifyNo;
              professionNumber.add(_professionNumber);
            }
            _professionImg.add(transferBean);
            break;
          case "QUALIFICATION":
            _qualificationImg.add(transferBean);
            break;
          case "TITLE":
            _titleCertificateImg.add(transferBean);
            break;
        }
      });
    }

    dealIsShowAddImgButton(_professionImg);
    professionPhoto.add(_professionImg);
    dealIsShowAddImgButton(_qualificationImg);
    qualificationPhoto.add(_qualificationImg);
    dealIsShowAddImgButton(_titleCertificateImg);
    titleCertificate.add(_titleCertificateImg);
  }

  void editIDCARDChanged(String value) {
    _idCard = value;
  }

  void editProfessionNumberChanged(String value) {
    _professionNumber = value;
  }

  dealIsShowAddImgButton(List<SaveCertifyPhotoBean.Data> list) {
    list.removeWhere(
            (element) => element.photoUrl.isEmpty || element.keyID == 'add');
    if (list.length < 9) {
      list.add(SaveCertifyPhotoBean.Data(photoUrl: '', keyID: 'add'));
    }
  }

  deleteCertify(SaveCertifyPhotoBean.Data data) async {
    var result = await LoginHttp.deleteCertificationPic(data.keyID);
    if (result.isSuccess) {
      switch (data.certifyCode) {
        case "ID-FRONT":
          _idCardImg.removeAt(0);
          idCardFront
              .add(SaveCertifyPhotoBean.Data(photoUrl: '', keyID: 'add'));
          break;
        case "ID-BACK":
          _idCardImg.removeAt(1);
          idCardBg.add(SaveCertifyPhotoBean.Data(photoUrl: '', keyID: 'add'));
          break;
        case "PROFESSION":
          _professionImg.removeWhere((element) => element.keyID == data.keyID);
          dealIsShowAddImgButton(_professionImg);
          professionPhoto.add(_professionImg);
          break;
        case "QUALIFICATION":
          _qualificationImg
              .removeWhere((element) => element.keyID == data.keyID);
          dealIsShowAddImgButton(_qualificationImg);
          qualificationPhoto.add(_qualificationImg);
          break;
        case "TITLE":
          _titleCertificateImg
              .removeWhere((element) => element.keyID == data.keyID);
          dealIsShowAddImgButton(_titleCertificateImg);
          titleCertificate.add(_titleCertificateImg);
          break;
      }
    } else {
      ToastUtil.error(result.error.msg);
    }
  }

  void uploadImage(BuildContext context, String path, String type) async {
    switch (type) {
      case TYPE_ID_FRONT:
        dealRealPicLogic(path, "ID-FRONT", "身份证正面", before: (data) {
          idCardFront.add(data);
        }, success: (data) {
          _idCardImg.insert(0, data);
          idCardFront.add(data);
        }, failure: (data) {
          idCardFront.add(data);
        }, keyID: _idCardImg.isEmpty ? '' : _idCardImg[0]?.keyID ?? '');
        break;

      case TYPE_ID_BACK:
        dealRealPicLogic(path, "ID-BACK", "身份证反面", before: (data) {
          idCardBg.add(data);
        }, success: (data) {
          _idCardImg.insert(1, data);
          idCardBg.add(data);
        }, failure: (data) {
          idCardBg.add(data);
        }, keyID: _idCardImg.length < 2 ? '' : _idCardImg[1]?.keyID ?? '');
        break;

      case TYPE_PROFESSION:
        dealRealPicLogic(path, "PROFESSION", "执业证书", before: (data) {
          _professionImg.forEach((element) {
            if (element.keyID == data.keyID) {
              element.photoUrl = data.photoUrl;
            }
          });
          professionPhoto.add(_professionImg);
        }, success: (data) {
          _professionImg.add(data);
          dealIsShowAddImgButton(_professionImg);
          professionPhoto.add(_professionImg);
        }, failure: (data) {
          _professionImg.forEach((element) {
            if (element.keyID == data.keyID) {
              element.photoUrl = data.photoUrl;
            }
          });
          professionPhoto.add(_professionImg);
        });
        break;

      case TYPE_QUALIFICATION:
        dealRealPicLogic(
          path,
          "QUALIFICATION",
          "资格证书",
          before: (data) {
            _qualificationImg.forEach((element) {
              if (element.keyID == data.keyID) {
                element.photoUrl = data.photoUrl;
              }
            });
            qualificationPhoto.add(_qualificationImg);
          },
          success: (data) {
            _qualificationImg.add(data);
            dealIsShowAddImgButton(_qualificationImg);
            qualificationPhoto.add(_qualificationImg);
          },
          failure: (data) {
            _qualificationImg.forEach((element) {
              if (element.keyID == data.keyID) {
                element.photoUrl = data.photoUrl;
              }
            });
            qualificationPhoto.add(_qualificationImg);
          },
        );
        break;

      case TYPE_TITLE_CERTIFICATE:
        dealRealPicLogic(
          path,
          "TITLE",
          "职称证书",
          before: (data) {
            _titleCertificateImg.forEach((element) {
              if (element.keyID == data.keyID) {
                element.photoUrl = data.photoUrl;
              }
            });
            titleCertificate.add(_titleCertificateImg);
          },
          success: (data) {
            _titleCertificateImg.add(data);
            dealIsShowAddImgButton(_titleCertificateImg);
            titleCertificate.add(_titleCertificateImg);
          },
          failure: (data) {
            _titleCertificateImg.forEach((element) {
              if (element.keyID == data.keyID) {
                element.photoUrl = data.photoUrl;
              }
            });
            titleCertificate.add(_titleCertificateImg);
          },
        );
        break;
    }
  }

  Future<ResultBody<UploadBean.Data>> doUpload(path) {
    //   ..['belongID'] = _doctorUser.keyID
    // systemCode: "DOCTOR",
    // belongCode: "CERTIFY",
    // width: "500",
    // height: "500"
    return FileHttp.upload(Map()
      ..["file"] = File(path),
        params: Map()
          ..['belongID'] = _doctorUser.keyID
          ..['systemCode'] = 'DOCTOR'
          ..['belongCode'] = 'CERTIFY'
          ..['width'] = '500'
          ..['height'] = '500');
  }

  dealRealPicLogic(String path, String certifyCode, String certifyName,
      {Function(SaveCertifyPhotoBean.Data data) before,
        Function(SaveCertifyPhotoBean.Data data) success,
        Function(SaveCertifyPhotoBean.Data data) failure,
        keyID = ""}) async {
    var beforeBean = SaveCertifyPhotoBean.Data(photoUrl: '-', keyID: 'add');
    var failBean = SaveCertifyPhotoBean.Data(photoUrl: '', keyID: 'add');
    before.call(beforeBean);
    var result = await doUpload(path);
    if (result.isSuccess) {
      var photoData = Map<String, String>()
        ..['keyID'] = keyID
        ..['photoUrl'] = result.data.remoteAddress
        ..['photoFileID'] = result.data.keyID
        ..['certifyCode'] = certifyCode
        ..['certifyName'] = certifyName
        ..['doctorID'] = _doctorUser.keyID;

      var saveResult = await LoginHttp.addCertificationPic(photoData);

      if (saveResult.isSuccess) {
        success.call(saveResult.data);
      } else {
        failure.call(failBean);
        ToastUtil.error(result.error.msg);
      }
    } else {
      failure.call(failBean);
      ToastUtil.error(result.error.msg);
    }
  }


  static const regEn = "^[`~!@#\$%^&*()_+<>?:\"{},.\/;'[\]]/";

  static const regCn = '^[·！#￥（——）：；“”‘、，|《。》？、【】[\]]';

  saveCertificationInfo(context) {
    if (_idCardImg.isNotEmpty && _idCardImg[0] == null) {
      ToastUtil.warning('请上传身份证国徽面');
      return;
    }

    if (_idCardImg.isNotEmpty && _idCardImg[1] == null) {
      ToastUtil.warning('请上传身份证头像面');
      return;
    }
    if (_professionImg.length < 2) {
      ToastUtil.warning('请上传执业证，至少2页');
      return;
    }
    if (_qualificationImg.length < 2) {
      ToastUtil.warning('请上传资格证，至少2页');
      return;
    }

    if (_idCard.isEmpty) {
      ToastUtil.warning('请输入身份证号');
      return;
    }

    if (!RegexUtil.isIDCard(_idCard)) {
      ToastUtil.warning('请输入合法身份证号');
      return;
    }

    if (_professionNumber.isEmpty) {
      ToastUtil.warning('请输入执业证书编号');
      return;
    }
    // 执业证书编号特殊符号校验
    if (RegexUtil.matches(regCn, _professionNumber) ||
        RegexUtil.matches(regEn, _professionNumber)) {
      ToastUtil.warning('执业证书编号不能包含特殊字符');
      return;
    }


    saveDoctorCertifyNo(context);
  }

  void saveDoctorCertifyNo(context) async {
    loadingStatus.add(true);

    var idCertifyNoData = Map()
      ..['doctorID'] = _doctorUser.keyID
      ..['certifyCode'] = 'ID-BACK'
      ..['certifyName'] = '身份证反面'
      ..['certifyNo'] = _idCard;

    var professionCertifyNoData = Map()
      ..['doctorID'] = _doctorUser.keyID
      ..['certifyCode'] = 'PROFESSION'
      ..['certifyName'] = '执业证书'
      ..['certifyNo'] = _professionNumber;

    var result = await LoginHttp.saveCertificationNumber(
        "[${json.encode(idCertifyNoData)},${json.encode(
            professionCertifyNoData)}]");

    if (result.isSuccess) {
      saveDoctorCommitToReview(context);
    } else {
      loadingStatus.add(false);
      ToastUtil.error(result.error.msg);
    }
  }

  void saveDoctorCommitToReview(context) async {
    var result = await LoginHttp.commitCertificationInfo(_doctorUser.keyID);
    if (result.isSuccess) {
      loadingStatus.add(false);
      Routers.navigateTo(context, DoctorLoginComponent.auditingPage,
          clearStack: true);
    } else {
      loadingStatus.add(false);
      ToastUtil.error(result.error.msg);
    }
  }
}
